/**
 * The MarketController class has a buy and sell method along side methods to check the 
 * inventories of the Trader and Player. It also takes in a Player and a trader as a 
 * Constructor.
 * @author Team Love is Like Sand
 * @version 1.0
 * 
 */

import java.awt.Toolkit;
import java.awt.Cursor;
import java.awt.Image;
import java.awt.Point;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

/**
 * Controller for market
 * @author kushagramansingh
 * @version 1.0
 */
public class MarketController {
	
	/**
	 * Inventory of the trader
	 */
	private Inventory traderInventory;
	
	/**
	 * Inventory of the player
	 */
	private Inventory playerInventory;
	
	/**
	 * The player
	 */
	private Player player;
	
	/**
	 * The trader
	 */
	private Trader trader;
	
	/**
	 * The data backing the market
	 */
	private String[][] data;
	
	/**
	 * if player is still trading
	 */
	private boolean trading;
	
	/**
	 * The universe map
	 */
	private JFrame map;
	
	/**
	 * Constructor that initializes instance variables
	 * @param p Player 
	 * @param t Trader
	 * @param map of the Universe
	 */
	public MarketController(Player p, Trader t, JFrame map){
		traderInventory = t.getInventory();
		playerInventory = p.getInventory();
		trader = t;
		player = p;
		this.map = map;
		trading = true;
	}
	
	/**
	 * Returns solar system that the player is in
	 * @return current system
	 */
	public SolarSystem getSystem(){
		return player.getSystem();
	}
	
	/**
	 * Returns a 2d array of strings that represents buying and selling data
	 * @param data
	 * @param frame
	 * @return resetTable()
	 */
	public String[][] buySell(String[][] data, JFrame frame){
		int amt;
		for(int i = 0; i < Inventory.GOODLIST.length; i++){
			if(!data[i][6].equals("0")){
				try{
					amt = Integer.parseInt((data[i][6]));
					if(amt > playerInventory.getInventory()[i].getNumber()){
						errorMessage(frame, "You dont have enough of those to sell!");
						return resetTable();
					}
					if(amt * Integer.parseInt(data[i][2]) > traderInventory.getMoney()){
						errorMessage(frame, "The Trader does not have enough money!");
						return resetTable();
					}
					playerInventory.addItem(Inventory.GOODLIST[i], -amt);
					player.addCargo(-amt * Inventory.GOODLIST[i].getSize());
					playerInventory.addMoney(amt * Integer.parseInt(data[i][2]));
					traderInventory.addMoney(-amt * Integer.parseInt(data[i][2]));
					traderInventory.addItem(Inventory.GOODLIST[i], amt);
				}
				catch(NumberFormatException e){
					errorMessage(frame, "You must input numbers to the buy/sell columns");
					e.getStackTrace();
					return resetTable();
				}
				
			}
			if(!data[i][5].equals("0")){
				try{
					amt = Integer.parseInt(data[i][5]);
					if(amt * Inventory.GOODLIST[i].getSize() > player.getFreeCargoSpace()){
						errorMessage(frame, "You don't have enough space for these items!");
						return resetTable();
					}
					if(amt * Integer.parseInt(data[i][1]) > playerInventory.getMoney()){
						errorMessage(frame, "You don't have enough money " +
									"to pay for all these items!");
						return resetTable();
					}
					if(amt > traderInventory.getInventory()[i].getNumber()){
						errorMessage(frame, "The Trader does not have enough " +
									"of those to sell to you!");
						return resetTable();
					}
					playerInventory.addItem(Inventory.GOODLIST[i], amt);
					player.addCargo(amt * Inventory.GOODLIST[i].getSize());
					playerInventory.addMoney(-amt * Integer.parseInt(data[i][1]));
					traderInventory.addMoney(amt * Integer.parseInt(data[i][1]));
					traderInventory.addItem(Inventory.GOODLIST[i], -amt);
				}
				catch(NumberFormatException e){
					errorMessage(frame, "You must input numbers to the buy/sell columns");
					e.getStackTrace();
					return resetTable();
				}
			}
		}
		return resetTable();
	}
	
	/**
	 * Returns a 2d array of strings that represents buying and selling data
	 * @return data
	 */
	public String[][] resetTable(){
		data = new String[Inventory.GOODLIST.length][7];
		double delta = (.75 * (player.getTrading() - 
						(trader.getTrade() + player.getDifficulty()))) / 13.0 - .25;
		for(int i = 0; i < data.length; i++){
			data[i] = new String[] {Inventory.GOODLIST[i].getName(), 
									"" +
									(int) (trader.getPriceList()[i].getNumber() *
											(1 - delta)),
									"" +
									(int) (trader.getPriceList()[i].getNumber() *
											(1 + delta)),
									"" +
									(playerInventory.getInventory()[i].getNumber()),
									"" +
									(traderInventory.getInventory()[i].getNumber()),
									"0",
									"0",
									"" + Inventory.GOODLIST[i].getSize()};
		}
		return data;
	}
	
	/**
	 * Returns the money of a trader in a String
	 * @return "Seller Cash: " + traderInventory.getMoney();
	 */
	public String resetTraderBar(){
		return "Seller Cash: " + traderInventory.getMoney();
	}
	
	/**
	 * Checks for trading
	 * @return trading
	 */
	public boolean isTrading(){
		return trading;
	}
	
	/**
	 * Ends trading 
	 * @param frame
	 */
	public void endTrading(JFrame frame){
		trading = false;
		frame.dispose();
		((UniverseMap) map).updateMap();
		map.setVisible(true);

		//Sets cursor
		ImageIcon cursor = new ImageIcon("Images/cursor.gif"); 
		Image shipCursor = cursor.getImage();

		Cursor newCursor = Toolkit.getDefaultToolkit().createCustomCursor(
						shipCursor, new Point(10, 10), "Ship Cursor");
		map.setCursor(newCursor);
	}
	
	/**
	 * Sets up and displays error messages.
	 * @param frame
	 * @param message
	 */
	private void errorMessage(JFrame frame, String message){
		JOptionPane.showMessageDialog(frame, message);
	}
}
